package com.info.zhiduoduo.admin.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.mapper.Condition;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.info.zhiduoduo.admin.model.formbean.company.CompanyListFormBean;
import com.info.zhiduoduo.admin.model.formbean.company.PartnerMakerDetailListFormBean;
import com.info.zhiduoduo.admin.model.formbean.partner.*;
import com.info.zhiduoduo.admin.model.vo.partner.PartnerKpiDataVO;
import com.info.zhiduoduo.admin.model.vo.partner.WriteOffBrokerageVO;
import com.info.zhiduoduo.common.configs.DocConfig;
import com.info.zhiduoduo.common.configs.PayConfig;
import com.info.zhiduoduo.common.configs.ZddUrlConfig;
import com.info.zhiduoduo.common.constants.Constants;
import com.info.zhiduoduo.common.constants.SmartResult;
import com.info.zhiduoduo.common.constants.StatusMsg;
import com.info.zhiduoduo.common.constants.partner.*;
import com.info.zhiduoduo.common.constants.project.CalcAmountType;
import com.info.zhiduoduo.common.constants.project.CompanyProjectState;
import com.info.zhiduoduo.common.exception.Asserts;
import com.info.zhiduoduo.common.formbean.BaseSimpleFormBean;
import com.info.zhiduoduo.common.utils.DateUtil;
import com.info.zhiduoduo.common.utils.EasyExcelUtil;
import com.info.zhiduoduo.common.utils.LogUtil;
import com.info.zhiduoduo.common.utils.MD5Util;
import com.info.zhiduoduo.common.utils.NumberUtil;
import com.info.zhiduoduo.common.utils.RandomUtil;
import com.info.zhiduoduo.common.utils.StringUtil;
import com.info.zhiduoduo.core.dto.zhaoshang.ZhaoShangPayDetailedDTO;
import com.info.zhiduoduo.core.dto.zhaoshang.ZhaoShangQueryPayDetailedFormBean;
import com.info.zhiduoduo.core.service.CommonService;
import com.info.zhiduoduo.core.service.CoreBrokerageService;
import com.info.zhiduoduo.core.service.CorePartnerService;
import com.info.zhiduoduo.core.service.CoreProjectService;
import com.info.zhiduoduo.core.service.WxMessageService;
import com.info.zhiduoduo.core.service.WxPartnerMessageService;
import com.info.zhiduoduo.core.service.common.BaseService;
import com.info.zhiduoduo.repository.dto.company.CompanyBriefDto;
import com.info.zhiduoduo.repository.dto.company.CompanyVerifyBriefDto;
import com.info.zhiduoduo.repository.dto.crm.PartnerKpiDto;
import com.info.zhiduoduo.repository.dto.maker.MakerDetailDto;
import com.info.zhiduoduo.repository.dto.maker.StudioDetailDto;
import com.info.zhiduoduo.repository.dto.partner.CommissionRecordDto;
import com.info.zhiduoduo.repository.dto.partner.MakerRelationshipDto;
import com.info.zhiduoduo.repository.dto.partner.OnlineEnterprisesDto;
import com.info.zhiduoduo.repository.dto.partner.PartnerAndCompanyRelationshipDto;
import com.info.zhiduoduo.repository.dto.partner.PartnerAndPhoneDto;
import com.info.zhiduoduo.repository.dto.partner.PartnerBriefDto;
import com.info.zhiduoduo.repository.dto.partner.PartnerCompanyExpireDto;
import com.info.zhiduoduo.repository.dto.partner.PartnerCrowdCostDto;
import com.info.zhiduoduo.repository.dto.partner.PartnerCrowdsourceSubDto;
import com.info.zhiduoduo.repository.dto.partner.PartnerDetailDto;
import com.info.zhiduoduo.repository.dto.partner.PartnerExpireDto;
import com.info.zhiduoduo.repository.dto.partner.PartnerGivenFieldDto;
import com.info.zhiduoduo.repository.dto.partner.PartnerMakerDetailDto;
import com.info.zhiduoduo.repository.dto.partner.PartnerMakerExpireDto;
import com.info.zhiduoduo.repository.dto.partner.PartnerMonthBrokerageDto;
import com.info.zhiduoduo.repository.dto.partner.PartnerNameDto;
import com.info.zhiduoduo.repository.dto.partner.PartnerStudioRemitProjectExportDto;
import com.info.zhiduoduo.repository.dto.partner.PartnerStudioWithdrawDto;
import com.info.zhiduoduo.repository.dto.partner.PartnerSubDto;
import com.info.zhiduoduo.repository.dto.partner.RelationshipDto;
import com.info.zhiduoduo.repository.entity.company.Company;
import com.info.zhiduoduo.repository.entity.company.CompanyProject;
import com.info.zhiduoduo.repository.entity.crm.CrmSystemManager;
import com.info.zhiduoduo.repository.entity.crm.IntentionPartner;
import com.info.zhiduoduo.repository.entity.order.TradeRecord;
import com.info.zhiduoduo.repository.entity.partner.*;
import com.info.zhiduoduo.repository.entity.system.BusinessManager;
import com.info.zhiduoduo.repository.mapper.company.CompanyMapper;
import com.info.zhiduoduo.repository.mapper.company.CompanyProjectMapper;
import com.info.zhiduoduo.repository.mapper.crm.CrmKpiMapper;
import com.info.zhiduoduo.repository.mapper.crm.IntentionPartnerMapper;
import com.info.zhiduoduo.repository.mapper.maker.MakerStudioMapper;
import com.info.zhiduoduo.repository.mapper.partner.PartnerAccountMapper;
import com.info.zhiduoduo.repository.mapper.partner.PartnerBankcardMapper;
import com.info.zhiduoduo.repository.mapper.partner.PartnerBrokerageMapper;
import com.info.zhiduoduo.repository.mapper.partner.PartnerCompanyMapper;
import com.info.zhiduoduo.repository.mapper.partner.PartnerCrowdsourceSubMapper;
import com.info.zhiduoduo.repository.mapper.partner.PartnerMakerMapper;
import com.info.zhiduoduo.repository.mapper.partner.PartnerMapper;
import com.info.zhiduoduo.repository.mapper.partner.PartnerMonthlyCrowdCostMapper;
import com.info.zhiduoduo.repository.mapper.partner.PartnerRecommendCompanyMapper;
import com.info.zhiduoduo.repository.mapper.partner.PartnerStudioWithdrawMapper;
import com.info.zhiduoduo.repository.mapper.partner.PartnerSubMapper;

import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.validator.constraints.Range;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class PartnerService extends BaseService {

	@Autowired
	WxPartnerMessageService wxPartnerMessageService;
	@Autowired
	WxMessageService wxMessageService;
	@Autowired
	CorePartnerService corePartnerService;
	@Autowired
	CommonService commonService;
	@Autowired
	CoreBrokerageService coreBrokerageService;
	@Autowired
	CoreProjectService coreProjectService;
	@Autowired
	MakerService makerService;

	@Resource
	PartnerMapper partnerMapper;
	@Resource
	PartnerSubMapper partnerSubMapper;
	@Resource
	PartnerCrowdsourceSubMapper partnerCrowdsourceSubMapper;
	@Resource
	PartnerAccountMapper partnerAccountMapper;
	@Resource
	PartnerBrokerageMapper partnerBrokerageMapper;
	@Resource
	PartnerCompanyMapper partnerCompanyMapper;
	@Resource
	PartnerMakerMapper partnerMakerMapper;
	@Resource
	PartnerBankcardMapper partnerBankcardMapper;
	@Resource
	CompanyMapper companyMapper;
	@Resource
	PartnerRecommendCompanyMapper partnerRecommendCompanyMapper;
	@Resource
	CrmKpiMapper crmKpiMapper;
	@Resource
	CompanyProjectMapper companyProjectMapper;
	@Resource
	IntentionPartnerMapper intentionPartnerMapper;
	@Resource
	PartnerStudioWithdrawMapper partnerStudioWithdrawMapper;
	@Resource
	MakerStudioMapper makerStudioMapper;
	@Resource
	PartnerMonthlyCrowdCostMapper partnerMonthlyCrowdCostMapper;

	@Autowired
	ZddUrlConfig zddUrlConfig;
	@Autowired
	PayConfig payConfig;
	@Autowired
	DocConfig docConfig;

	/**
	 * 获取合伙人信息
	 *
	 * @param formBean
	 * @return
	 */
	public SmartResult getPartnerInfo(BaseSimpleFormBean<GetPartnerInfoFormBean> formBean) {
		SmartResult smartResult = new SmartResult();
		if (null == formBean.getReqdata() || 0 == formBean.getReqdata().getPartnerid()) {
			smartResult.setStateMsg(StatusMsg.StatusMsg_101);
			return smartResult;
		}
		PartnerDetailDto partnerDetailDto = partnerMapper.getPartnerDetail(formBean.getReqdata().getPartnerid());
		if (null == partnerDetailDto) {
			smartResult.setStateMsg(StatusMsg.StatusMsg_501);
			return smartResult;
		}
		smartResult.setObject(partnerDetailDto);
		return smartResult;
	}

	/**
	 * 获取未审核,审核中的合伙人列表
	 *
	 * @param formBean
	 * @return
	 */
	public SmartResult<PartnerBriefDto> getVerifyingPartnerList(BaseSimpleFormBean<PartnerListFormBean> formBean) {
		PartnerListFormBean reqdata = formBean.getReqdata();
		if (reqdata == null) return errorParamSmartResult();
		int state = reqdata.getState();
		String inviter = reqdata.getInviter();
		String name = reqdata.getName();
		String businessManager = reqdata.getBusinessManager();
		int expire = reqdata.getExpire();
		int whetherCrowdPartner = reqdata.getWhetherCrowdPartner();
		int crowdCostState = reqdata.getCrowdCostState();
		String userName = reqdata.getUserName();
		Integer vaccineFlag = reqdata.getVaccineFlag();
		String marketingCooperativeCompname = reqdata.getMarketingCooperativeCompname();
		Integer boundEnterprise = reqdata.getBoundEnterprise();

		Page<Object> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		List<PartnerBriefDto> list = partnerAccountMapper.getVerifyingPartnerList(inviter, state, name, businessManager, expire,
				whetherCrowdPartner, crowdCostState,userName, vaccineFlag, marketingCooperativeCompname,boundEnterprise);
		structurePartnerData(list, state);
		return smartResult(list, page.getTotal(), page.getPages(), page.getPageNum());
	}

	//构建合伙人返回列表
	private List<PartnerBriefDto> structurePartnerData(List<PartnerBriefDto> list, int state) {
		if (null != list) {
			for (PartnerBriefDto dto : list) {
				int partnerid = dto.getPartnerid();
				if (0 != partnerid) {
					//计算未提现金额
					BigDecimal unremitBrokerage = partnerBrokerageMapper.getTotalBrokerageWithState(partnerid,
							PartnerBrokerageState.SETTLED);
					// 加上众包成本佣金
					unremitBrokerage = unremitBrokerage.add(
							partnerMonthlyCrowdCostMapper.sumPartnerBrokerage(partnerid, PartnerCrowdsourceCostState.UNSETTLED));
					dto.setNoCash(unremitBrokerage);

					//计算已提现金额
					BigDecimal remitBrokerage = partnerBrokerageMapper.getTotalBrokerageWithState(partnerid,
							PartnerBrokerageState.WITHDRAWED);
					remitBrokerage = remitBrokerage.add(
							partnerBrokerageMapper.getTotalBrokerageWithState(partnerid, PartnerBrokerageState.WITHDRAWING));
					// 加上众包成本佣金
					remitBrokerage = remitBrokerage.add(
							partnerMonthlyCrowdCostMapper.sumPartnerBrokerage(partnerid, PartnerCrowdsourceCostState.WITHDRAWING));
					remitBrokerage = remitBrokerage.add(
							partnerMonthlyCrowdCostMapper.sumPartnerBrokerage(partnerid, PartnerCrowdsourceCostState.WITHDRAWED));
					dto.setHasBeenProposed(remitBrokerage);

					if (4 == state) {
						//构建合伙人与企业的关系
						List<PartnerCompany> partnerCompanyList = partnerCompanyMapper.getPartnerCompanyByPartnerId(partnerid);
						if (null != partnerCompanyList) {
							List<RelationshipDto> relationshipDtoList = new ArrayList<>();
							for (PartnerCompany partnerCompany : partnerCompanyList) {
								RelationshipDto relationshipDto = new RelationshipDto();
								Company company = new Company().selectById(partnerCompany.getCompid());
								if (null != company && StringUtil.isNotEmpty(company.getCompname())) {
									relationshipDto.setCompname(company.getCompname());
								}
								relationshipDto.setType(partnerCompany.getType());
								relationshipDto.setRatio(partnerCompany.getRatio());
								relationshipDtoList.add(relationshipDto);
							}
							dto.setRelationshipList(relationshipDtoList);
						}

						// 构建合伙人与创客的关系
						List<PartnerMaker> partnerMakerList = partnerMakerMapper.getPartnerMakerByPartnerId(partnerid);
						if (null != partnerMakerList) {
							List<MakerRelationshipDto> relationshipList = new ArrayList<>();
							for (PartnerMaker partnerMaker : partnerMakerList) {
								MakerRelationshipDto relationshipDto = new MakerRelationshipDto();
								MakerDetailDto maker = makerService.getUserInfo(partnerMaker.getUserid());
								if (maker != null) {
									relationshipDto.setRealname(maker.getRealname()).setUsername(maker.getUsername());
								}
								relationshipDto.setType(partnerMaker.getType()).setRatio(partnerMaker.getRatio());
								relationshipList.add(relationshipDto);
							}
							dto.setMakerRelationshipList(relationshipList);
						}

						//构建二级合伙人信息
						dto.setSubPartnerCount(partnerSubMapper.countSubPartner(partnerid));
						PartnerSubDto upPartner = partnerSubMapper.findUpPartnerBySubId(partnerid);
						if (upPartner != null) dto.setUpPartnerid(upPartner.getPartnerid()).setUpPartnerName(upPartner.getPartnerName());

						// 众包合伙人信息
						dto.setSubCrowdPartnerCount(partnerCrowdsourceSubMapper.countSubPartner(partnerid));
						PartnerCrowdsourceSubDto upCrowdPartner = partnerCrowdsourceSubMapper.findUpPartnerBySubId(partnerid);
						if (upCrowdPartner != null)
							dto.setUpCrowdPartnerid(upCrowdPartner.getPartnerid()).setUpCrowdPartnerName(upCrowdPartner.getPartnerName());
					}
				}
			}
		}
		return list;
	}

	/**
	 * 获取上线企业列表
	 */
	public SmartResult getGoOnlineCompanyList(BaseSimpleFormBean<CompanyListFormBean> formBean) {
		CompanyListFormBean reqdata = formBean.getReqdata();
		//判断参数是否为空
		if (reqdata == null) return errorParamSmartResult();
		//构建查询条件
		Date startDate = reqdata.getStartDate();
		Date endDate = reqdata.getEndDate();
		String name = reqdata.getName();
		int state = reqdata.getState();
		String inviter = reqdata.getInviter();
		String businessManager = reqdata.getBusinessManager();

		if (startDate == null) startDate = new Date(0);
		if (endDate == null) endDate = new Date();
		//分页
		Page<Object> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		//查询所有上线企业
		List<CompanyVerifyBriefDto> list = companyMapper.getCompanyList(name,reqdata.getCompid(), inviter, businessManager, state, 0, null, startDate, endDate,
				null, null, null, null, null, null, null,null,null,null,null,null,null);
		//构建返回参数
		List<OnlineEnterprisesDto> onlineEnterprisesDtoList = new ArrayList<>();
		if (null != list) {
			//循环所有上线企业
			for (CompanyVerifyBriefDto companyVerifyBriefDto : list) {
				//返回的企业对象
				OnlineEnterprisesDto onlineEnterprisesDto = new OnlineEnterprisesDto();
				onlineEnterprisesDto.setCompid(companyVerifyBriefDto.getCompid());
				onlineEnterprisesDto.setCreatetime(companyVerifyBriefDto.getCreatetime());
				onlineEnterprisesDto.setCompname(companyVerifyBriefDto.getCompname());
				onlineEnterprisesDto.setContactname(companyVerifyBriefDto.getContactname());
				onlineEnterprisesDto.setContactphone(companyVerifyBriefDto.getContactphone());
				//基本服务费率总计
				BigDecimal basicServiceCostTotal = new BigDecimal("0");
				//项目服务费率总计
				BigDecimal projectServiceCostTotal = new BigDecimal("0");
				//智众包合伙人服务费率总计
				BigDecimal crowdsourceCostTotal = BigDecimal.ZERO;
				//查询合伙人与企业关系表
				List<PartnerAndCompanyRelationshipDto> partnerCompanyList = partnerCompanyMapper.getPartnerCompanyByCompId(companyVerifyBriefDto.getCompid());
				if (null != partnerCompanyList) {
					String partnerName = "";
					for (PartnerAndCompanyRelationshipDto partnerCompany : partnerCompanyList) {
						BigDecimal cost = BigDecimal.valueOf(partnerCompany.getRatio());
						//计算基本服务费总计和项目服务费总计
						if (1 == partnerCompany.getType()) {
							basicServiceCostTotal = basicServiceCostTotal.add(cost);
						} else if (2 == partnerCompany.getType()) {
							projectServiceCostTotal = projectServiceCostTotal.add(cost);
						} else if (3 == partnerCompany.getType()) {
							crowdsourceCostTotal = crowdsourceCostTotal.add(cost);
						}
						//构建合伙人姓名
						if (StringUtil.isEmpty(partnerCompany.getRealname())) {
							partnerName = partnerCompany.getRealname();
						} else {
							partnerName += "," + partnerCompany.getRealname();
						}
					}
					onlineEnterprisesDto.setPartner(partnerName);
					onlineEnterprisesDto.setPartnerAndCompanyRelationshipDtoList(partnerCompanyList);
				}
				onlineEnterprisesDto.setBasicServiceCostTotal(basicServiceCostTotal.doubleValue());
				onlineEnterprisesDto.setProjectServiceCostTotal(projectServiceCostTotal.doubleValue());
				onlineEnterprisesDto.setCrowdsourceServiceCostTotal(crowdsourceCostTotal.doubleValue());
				Integer crowdsourcePartnerId = companyVerifyBriefDto.getCrowdsourcePartnerId();
				if (crowdsourcePartnerId != 0) {
					PartnerAccount partnerAccount = new PartnerAccount().selectOne(
							Condition.create().eq("partnerid", crowdsourcePartnerId));
					onlineEnterprisesDto.setPartnerCrowdCostDto(
							new PartnerCrowdCostDto().setCrowdCostPrimaryRate(partnerAccount.getCrowdCostPrimaryRate())
									.setCrowdCostSecondaryAmount(partnerAccount.getCrowdCostSecondaryAmount())
									.setCrowdCostSecondaryRate(partnerAccount.getCrowdCostSecondaryRate())
									.setRealname(partnerAccount.getRealname()));

				}
				onlineEnterprisesDtoList.add(onlineEnterprisesDto);
			}
		}
		return smartResult(onlineEnterprisesDtoList, page.getTotal(), page.getPages(), page.getPageNum());
	}

	/**
	 * 获取企业合伙人分佣记录数据
	 */
	public SmartResult getCompanyPartnerList(BaseSimpleFormBean<Integer> formBean) {
		//返回企业与合伙人关系
		List<PartnerAndCompanyRelationshipDto> list = partnerCompanyMapper.getPartnerCompanyByCompId(formBean.getReqdata());
		return smartResult(list);
	}


	//查询所有合伙人
	public SmartResult getAllCertifiedPartner(BaseSimpleFormBean formBean) {
		Page<Object> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		List<PartnerAccount> partnerAccountList = partnerAccountMapper.getAllCertifiedPartner();
		List<PartnerAndPhoneDto> partnerAndPhoneDtoList = new ArrayList<>();
		if (null != partnerAccountList) {
			for (PartnerAccount partnerAccount : partnerAccountList) {
				PartnerAndPhoneDto partnerAndPhoneDto = new PartnerAndPhoneDto();
				if (0 != partnerAccount.getPartnerid()) {
					partnerAndPhoneDto.setPartnerid(partnerAccount.getPartnerid());
				}
				if (StringUtil.isNotEmpty(partnerAccount.getRealname())) {
					partnerAndPhoneDto.setRealname(partnerAccount.getRealname());
				}
				Partner partner = new Partner().selectById(partnerAccount.getPartnerid());
				if (null != partner && StringUtil.isNotEmpty(partner.getPhone())) {
					partnerAndPhoneDto.setPhone(partner.getPhone());
				}
				partnerAndPhoneDtoList.add(partnerAndPhoneDto);
			}
		}
		return smartResult(partnerAndPhoneDtoList, page.getTotal(), page.getPages(), page.getPageNum());
	}

	//新增合伙人与企业关系
	public SmartResult savePartnerCompany(BaseSimpleFormBean<SavePartnerCompanyFormBean> formBean) {
		SmartResult smartResult = new SmartResult();
		SavePartnerCompanyFormBean reqdata = formBean.getReqdata();
		//判断参数是否为空
		if (reqdata == null) return errorParamSmartResult();
		if (1 == reqdata.getFlag()) {
			PartnerCompany partnerCompany = new PartnerCompany();
			//COPY传回的参数
			BeanUtils.copyProperties(reqdata, partnerCompany);
			Asserts.notTrue(partnerCompanyMapper.existsByPartneridAndCompid(reqdata.getPartnerid(), reqdata.getCompid(),
							reqdata.getType()),
					StatusMsg.StatusMsg_509);

			if (partnerCompany.insert()) {
				wxPartnerMessageService.notifyPartnerCompanyAdded(partnerCompany);
			}
			smartResult.setObject(partnerCompany.getId());
		} else if (2 == reqdata.getFlag()) {
			if (0 == reqdata.getId()) {
				return errorParamSmartResult();
			}
			PartnerCompany partnerCompany = new PartnerCompany().selectById(reqdata.getId());
			if (null == partnerCompany) {
				return smartResult(StatusMsg.StatusMsg_504);
			}

			Double oldRatio = partnerCompany.getRatio();
			double newRatio = reqdata.getRatio();
			BeanUtils.copyProperties(reqdata, partnerCompany);
			boolean update = partnerCompany.updateById();
		}
		return smartResult;
	}

	//删除合伙人与企业关系（逻辑删除）
	public SmartResult deletePartnerCompany(BaseSimpleFormBean<DeletePartnerCompanyFormBean> formBean) {
		DeletePartnerCompanyFormBean deletePartnerCompanyFormBean = formBean.getReqdata();
		//判断参数是否为空
		if (deletePartnerCompanyFormBean == null || 0 == deletePartnerCompanyFormBean.getId()) return errorParamSmartResult();
		PartnerCompany partnerCompany = new PartnerCompany();
		if (!partnerCompany.deleteById(deletePartnerCompanyFormBean.getId())) {
			return optFailSmartResult();
		}
		return smartResult();
	}

	//新增合伙人与创客关系
	public SmartResult savePartnerMaker(BaseSimpleFormBean<SavePartnerMakerFormBean> formBean) {
		SmartResult smartResult = new SmartResult();
		SavePartnerMakerFormBean reqdata = formBean.getReqdata();
		//判断参数是否为空
		if (reqdata == null) return errorParamSmartResult();
		int id = reqdata.getId();
		PartnerMaker partnerMaker = new PartnerMaker().selectById(id);
		if (partnerMaker == null) {
			// 新建, 判断是否存在
			Asserts.notTrue(partnerMakerMapper.existsByPartneridAndUserid(reqdata.getPartnerid(), reqdata.getUserid(), reqdata.getType()),
					StatusMsg.StatusMsg_523);
			partnerMaker = new PartnerMaker();
		}
		// 更新数据
		BeanUtils.copyProperties(reqdata, partnerMaker);
		partnerMaker.insertOrUpdate();
		return SmartResult.success(partnerMaker.getId());
	}

	//删除合伙人与创客关系（逻辑删除）
	public SmartResult deletePartnerMaker(BaseSimpleFormBean<DeletePartnerMakerFormBean> formBean) {
		DeletePartnerMakerFormBean reqdata = formBean.getReqdata();
		//判断参数是否为空
		if (reqdata == null || 0 == reqdata.getId()) return errorParamSmartResult();
		PartnerMaker partnerMaker = new PartnerMaker();
		if (!partnerMaker.deleteById(reqdata.getId())) {
			return optFailSmartResult();
		}
		return smartResult();
	}

	public SmartResult<PartnerMakerDetailDto> listPartnerMakerDetails(BaseSimpleFormBean<PartnerMakerDetailListFormBean> formBean) {
		PartnerMakerDetailListFormBean reqdata = formBean.getReqdata();
		Date startDate = reqdata.getStartDate();
		Date endDate = reqdata.getEndDate();

		if (startDate == null) startDate = new Date(0);
		if (endDate == null) endDate = new Date();

		Page<PartnerMakerDetailDto> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		partnerMakerMapper.listValidMakers(reqdata.getName(), startDate, endDate)
				.forEach(dto -> dto.setPartnerMakerList(partnerMakerMapper.listByUserid(dto.getUserid())));
		return SmartResult.ofPage(page);
	}

	//新增合伙人项目佣金记录
	@Transactional
	public SmartResult savePartnerBrokerage(BaseSimpleFormBean<SavePartnerCommissionRecordFormBean> formBean) {
		SavePartnerCommissionRecordFormBean reqdata = formBean.getReqdata();
		Integer projectId = reqdata.getProjectId();
		Integer projectType = reqdata.getProjectType();
		Integer userid = reqdata.getUserid();
		Integer compid = reqdata.getCompid();

		if (userid == null) {
			userid = 0;
		}

		//检查企业是否存在
		if (reqdata.getCompid() != null && reqdata.getCompid() != 0) {
			int count = new Company().selectCount(Condition.create().eq("compid", reqdata.getCompid()));
			if (count == 0) return smartResult(StatusMsg.StatusMsg_302);
		}

		//校验合伙人
		Partner partner = partnerMapper.selectById(reqdata.getPartnerId());
		if (partner == null) {
			return smartResult(StatusMsg.StatusMsg_501);
		}

		String projectno = "";
		if (projectId == null || projectId == 0) {
			projectno = "N" + System.currentTimeMillis() / 1000;
		} else {
			projectno = "P" + StringUtil.toFixedLengthNum(projectId, 9);
		}
		//新增合伙人佣金
		PartnerBrokerage pb = new PartnerBrokerage().setBrokerageno(RandomUtil.createRandomNo("MT", ""))
				.setProjectid(projectId)
				.setProjectType(projectType)
				.setCompid(compid)
				.setUserid(userid)
				.setProjectdealamount(reqdata.getProjectdealamount())
				.setProjectservicecharge(reqdata.getProjectservicecharge())
				.setBrokerage(reqdata.getBrokerage())
				.setPartnerid(partner.getPartnerid())
				.setPartnerType(reqdata.getPartnerType())
				.setSettleType(BrokerageSettleType.AUTO)
				.setProjectno(projectno)
				.setState(2) //默认已结算未提现状态
				.setAdminid(formBean.getUserid())//记录当前操作人
				.setRemark(reqdata.getRemark());
		pb.insert();

		//生成合伙人账户流水记录
		int partnerType = NumberUtil.safeInt(pb.getPartnerType());
		String partnerTypeName = "";
		if (partnerType == PartnerBrokerageType.BASIC) {
			partnerTypeName = "基本服务费";
		} else if (partnerType == PartnerBrokerageType.PROJECT) {
			partnerTypeName = "项目服务费";
		} else if (partnerType == PartnerBrokerageType.CROWDSOURCE) {
			partnerTypeName = "智众包佣金";
		} else if (partnerType == PartnerBrokerageType.OTHER) {
			partnerTypeName = "其他佣金";
		}
		String flowname = "手动添加 " + partnerTypeName;
		new PartnerAccountflow().setPartnerid(pb.getPartnerid())
				.setCompid(pb.getCompid())
				.setUserid(pb.getUserid())
				.setBrokerageid(pb.getBrokerageid())
				.setProjectid(pb.getProjectid())
				.setProjectType(pb.getProjectType())
				.setTradeid(pb.getTradeid())
				.setAmounttype(partnerType)
				.setFlowAmount(pb.getBrokerage())
				.setFlowtype(1) //默认收入
				.setFlowname(flowname)
				.insert();
		return smartResult();
	}

	//查询合伙人项目佣金记录
	public SmartResult getAllCommissionRecord(BaseSimpleFormBean<PartnerBrokerageListFormBean> formBean) {
		//获取参数
		PartnerBrokerageListFormBean reqdata = formBean.getReqdata();
		//非空判断
		if (reqdata == null) return errorParamSmartResult();
		String whereStr = "";
		//查询参数
		String startDate = reqdata.getStartDate();
		String endDate = reqdata.getEndDate();
		String name = reqdata.getName();
		int state = reqdata.getState();
		int partnerType = reqdata.getPartnerType();
		int partnerAccountType = reqdata.getPartnerAccountType();
		int partnerRemitType = reqdata.getPartnerRemitType();
		int projectType = reqdata.getProjectType();

		if (StringUtil.isNotEmpty(startDate) && StringUtil.isNotEmpty(endDate)) {
			whereStr += " AND pb.createtime BETWEEN '" + startDate + "' AND '" + endDate + "' ";
		}
		if (StringUtil.isNotEmpty(name)) {
			whereStr += " AND concat(pa.realname,IFNUll(pb.brokerageno,''),IFNULL(pb.projectno,''),IFNULL(c.compname,'')) LIKE '%" + name +
					"%' ";
		}
		if (0 != state) {
			whereStr += " AND pb.state = '" + state + "' ";
		}
		if (0 != partnerType) {
			whereStr += " AND pb.partner_type = '" + partnerType + "' ";
		}
		if (0 != partnerAccountType) {
			whereStr += " AND pa.partner_type = '" + partnerAccountType + "' ";
		}
		if (0 != partnerRemitType) {
			whereStr += " AND pa.remit_type = " + partnerRemitType;
		}
		if (0 != projectType) {
			whereStr += " AND pb.project_type = " + projectType;
		}

		Page<CommissionRecordDto> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		partnerBrokerageMapper.getAllCommissionRecord(whereStr);
		double amount = partnerBrokerageMapper.statisticsAmountByType(whereStr);
		return smartResultPageAndObject(page, amount);
	}

	public void downloadCommissionRecord(HttpServletResponse response, String startDate, String endDate, String name, int state,
	                                     int partnerType, int partnerAccountType) {
		String whereStr = "";

		if (StringUtil.isNotEmpty(startDate) && StringUtil.isNotEmpty(endDate)) {
			whereStr += " AND pb.createtime BETWEEN '" + startDate + "' AND '" + endDate + "' ";
		}
		if (StringUtil.isNotEmpty(name)) {
			whereStr += " AND concat(pa.realname,IFNUll(pb.brokerageno,''),IFNULL(pb.projectno,''),IFNULL(c.compname,'')) LIKE '%" + name +
					"%' ";
		}
		if (0 != state) {
			whereStr += " AND pb.state = '" + state + "' ";
		}
		if (0 != partnerType) {
			whereStr += " AND pb.partner_type = '" + partnerType + "' ";
		}
		if (0 != partnerAccountType) {
			whereStr += " AND pa.partner_type = '" + partnerAccountType + "' ";
		}

		List<CommissionRecordDto> list = partnerBrokerageMapper.getAllCommissionRecord(whereStr);
		String fileName = "合伙人佣金记录";
		EasyExcelUtil.download(response, fileName, CommissionRecordDto.class, list);
	}

	/**
	 * 实名审核合伙人账号
	 * state 0:通过 1:驳回
	 *
	 * @param formBean
	 * @return
	 */
	public SmartResult verifyPartnerAccount(BaseSimpleFormBean<VerifyPartnerFormBean> formBean) {
		VerifyPartnerFormBean reqdata = formBean.getReqdata();
		if (reqdata == null || reqdata.getAcctid() <= 0) return errorParamSmartResult();

		int adminid = formBean.getUserid();
		int acctid = reqdata.getAcctid();
		int state = reqdata.getState();
		String reason = reqdata.getReason();
		String remark = reqdata.getRemark();
		Date expiredate = reqdata.getExpiredate();

		PartnerAccount partnerAccount = new PartnerAccount().selectById(acctid);
		if (partnerAccount == null) {
			return smartResult(StatusMsg.StatusMsg_501);
		} else if (partnerAccount.getRealnameAuth() >= Constants.partner_auth_4) {
			return smartResult(StatusMsg.StatusMsg_503);
		}

		if (0 == reqdata.getState()) {
			PartnerBankcard partnerBankcard = partnerBankcardMapper.getValidCard(partnerAccount.getPartnerid());
			if (null != partnerBankcard) {
				if (!partnerBankcard.getPayername().equals(partnerAccount.getRealname())) {
					return smartResult(StatusMsg.StatusMsg_511);
				}
			} else {
				return smartResult(StatusMsg.StatusMsg_510);
			}
		}

		if (null == expiredate) {
			Calendar curr = Calendar.getInstance();
			curr.set(Calendar.YEAR, curr.get(Calendar.YEAR) + 1);
			expiredate = curr.getTime();
		}

		int realnameAuth = state == 0 ? Constants.partner_auth_4 : Constants.partner_auth_3;
		//判断一下是审核通过还是退回，如果是通过的话，CRM那边需要取审核通过时间进行定时任务操作的
		if (Constants.partner_auth_4 == realnameAuth) {
			partnerAccount.setAuditPassTime(new Date());
		}

		BeanUtils.copyProperties(reqdata, partnerAccount);

		if (partnerAccount.setRealnameAuth(realnameAuth).setEffectivedate(new Date()).setExpiredate(expiredate).updateById()) {

			//如果是审核通过，根据名称去 CRM里查询是否有意向合伙人，如果有的话，绑定意向合伙人并将意向合伙人转为已注册
			if (Constants.partner_auth_4 == realnameAuth) {
				//可能会查到多条
				List<IntentionPartner> intentionPartnerList = intentionPartnerMapper.getIntentionPartnerByName(
						partnerAccount.getRealname());
				if (null != intentionPartnerList && intentionPartnerList.size() > 0) {
					//当只查到一条的时候进行操作，如果查到多条，需要去CRM手动关联
					if (1 == intentionPartnerList.size()) {
						IntentionPartner intentionPartner = intentionPartnerList.get(0);
						intentionPartner.setFlag(2);
						intentionPartner.setZddPartnerId(partnerAccount.getPartnerid());
						if (!intentionPartner.updateById()) {
							return optFailSmartResult();
						}
						//将意向合伙人中的数据带到实名表里面
						partnerAccount.setIntentionPartnerId(intentionPartner.getId());
						partnerAccount.setDevelopAbility(intentionPartner.getDevelopAbility());
						partnerAccount.setPotential(intentionPartner.getPotential());
						partnerAccount.setSource(intentionPartner.getPartnerSource());
						partnerAccount.setPartnerType(intentionPartner.getPartnerType());
						partnerAccount.setRemarks(intentionPartner.getRemarks());
						if (!partnerAccount.updateById()) {
							return optFailSmartResult();
						}
					}
				}
			}

			//如果是审核通过，防止重复点击导致插入多条数据
			if (state == 0) {
				PartnerAuthRecord record = new PartnerAuthRecord().selectOne(
						Condition.create().eq("acctid", acctid).orderBy("id", false).last(" limit 1"));
				if (record != null && record.getState() == 0) {
					//上一条已经是审核通过的记录，那么就不需要再记录了。
					return smartResult();
				}
			}

			new PartnerAuthRecord().setAdminid(adminid).setAcctid(acctid).setState(state).setReason(reason).setRemark(remark).insert();
			//结果通知创客
			wxPartnerMessageService.partnerAuthState(acctid);

			if (realnameAuth == Constants.partner_auth_4) {
				Partner partner = new Partner().selectById(partnerAccount.getPartnerid());
				//通知邀请者
				String inviteCode = partner.getInviteCode();
				if (StringUtil.isNotEmpty(inviteCode)) {
					PartnerAccount account = new PartnerAccount().selectOne(
							Condition.create().eq("promo_code", inviteCode).last(" limit 1"));
					if (account != null) {
						Partner promoPartner = new Partner().selectById(account.getPartnerid());
						wxPartnerMessageService.noticeInvitePartner(partnerAccount.getRealname(), promoPartner.getOpenid(),partnerAccount.getPartnerid());
					}
				}

				//通知商务经理
				new Thread(
						() -> commonService.sendEnterpriseWeChatNotice(partnerAccount.getBusinessManagerId(), partnerAccount.getRealname(),
								1)).start();
			}
		} else {
			return optFailSmartResult();
		}
		return smartResult();
	}

	//编辑实名信息
	public SmartResult updatePartnerAccount(BaseSimpleFormBean<UpdatePartnerAccountFormBean> formBean) {
		UpdatePartnerAccountFormBean reqdata = formBean.getReqdata();
		if (reqdata == null || reqdata.getPartnerid() <= 0) return errorParamSmartResult();

		int partnerid = reqdata.getPartnerid();
		PartnerAccount partnerAccount = partnerAccountMapper.selectByPartnerId(partnerid);
		if (null == partnerAccount) {
			return smartResult(StatusMsg.StatusMsg_501);
		}
		// 记录当前 合伙人 的商务经理
		Integer managerId = partnerAccount.getBusinessManagerId();

		BeanUtils.copyProperties(reqdata, partnerAccount);
		partnerAccount.updateById();
		Partner partner = new Partner().selectById(partnerid);
		partner.setInviteCode(reqdata.getInviteCode()).setPartnerid(partnerid).setNoticeFlag(reqdata.getNoticeFlag()).updateById();

		//修改银行卡
		PartnerBankcard bankcard = partnerBankcardMapper.getValidCard(partnerid);
		if (bankcard == null) {
			bankcard = new PartnerBankcard().setPartnerid(partnerid).setState(1);
		}
		bankcard.setPayername(reqdata.getPayername())
				.setIdno(reqdata.getAcctIdno())
				.setAcctno(reqdata.getAcctno())
				.setBankname(reqdata.getBankname())
				.setTelephone(reqdata.getAcctphone());

		if (!bankcard.insertOrUpdate()) {
			return optFailSmartResult();
		}

		// 合伙人变更商务经理时，发消息给商务经理
		if (reqdata.getBusinessManagerId() > 0) {
			// 更改商务经理
			if (managerId != null && reqdata.getBusinessManagerId() != managerId) {
				CrmSystemManager nowSystemManager = new CrmSystemManager().selectOne(
						Condition.create().eq("business_manager_id", reqdata.getBusinessManagerId()).eq("state", 1));
				if (null == nowSystemManager) {
					return smartResult(StatusMsg.StatusMsg_335);
				}
				String text = "当前合伙人" + reqdata.getRealname() + "的商务经理更换为您，请注意查看！";
				commonService.sendEnterpriseWeChatNotice(reqdata.getBusinessManagerId(), "", 1, text);
			}
		}
		return smartResult();
	}

	public void queryWithdrawState(PartnerWithdraw withdraw) {
		LogUtil.info("每分钟检查提现结果.withdraw id = " + withdraw.getWdid());

		//切换成查询招商支付
		ZhaoShangQueryPayDetailedFormBean formBean = ZhaoShangQueryPayDetailedFormBean.of(withdraw.getPartnerOrderNo());
		SmartResult smartResult = new RestTemplate().postForObject(zddUrlConfig.getBasePayUrl() + payConfig.getZhaoShangQueryAgentPayUrl(),
				formBean, SmartResult.class);
		if (smartResult.getObject() != null && smartResult.isSuccessful()) {
			ZhaoShangPayDetailedDTO payResult = JSON.parseObject(JSON.toJSONString(smartResult.getObject()),
					new TypeReference<ZhaoShangPayDetailedDTO>() {
					});
			String errormsg = "";
			if (StringUtil.isNotEmpty(payResult.getErrtxt())) {
				errormsg = payResult.getErrtxt();
			} else {
				errormsg = payResult.getErrdsp();
			}
			corePartnerService.handleZhaoShangsWithdrawTradeState(withdraw, payResult.getStscod(), payResult.getErrcod(), errormsg);
		}
	}

	public SmartResult changeState(BaseSimpleFormBean<ChangePartnerStateFormBean> formBean) {
		ChangePartnerStateFormBean reqdata = formBean.getReqdata();
		if (reqdata == null) return errorParamSmartResult();

		int partnerid = reqdata.getPartnerid();

		if (reqdata.getState() == 1) {
			//变成审核中状态
			new PartnerAccount().setRealnameAuth(Constants.partner_auth_2).update(Condition.create().eq("partnerid", partnerid));
		}
		return smartResult();
	}

	public SmartResult delPartner(BaseSimpleFormBean<Integer> formBean) {
		Integer partnerid = formBean.getReqdata();

		if (new PartnerBrokerage().selectCount(Condition.create().eq("partnerid", partnerid)) > 0) {
			return optFailSmartResult();
		}
		partnerMapper.delPartner(partnerid);
		return smartResult();
	}

	public SmartResult editInviteCode(BaseSimpleFormBean<EditInviteCodeFormBean> formBean) {
		EditInviteCodeFormBean reqdata = formBean.getReqdata();
		if (reqdata == null) return errorParamSmartResult();

		int partnerid = reqdata.getPartnerid();
		String inviteCode = reqdata.getInviteCode();

		new Partner().setPartnerid(partnerid).setInviteCode(inviteCode).updateById();
		return smartResult();
	}

	/**
	 * 获取合同中某些合伙人字段
	 *
	 * @param formBean
	 * @return
	 */
	public SmartResult queryGivenField(BaseSimpleFormBean<GetPartnerInfoFormBean> formBean) {
		GetPartnerInfoFormBean reqdata = formBean.getReqdata();
		if (null == reqdata || 0 == reqdata.getPartnerid()) {
			return errorParamSmartResult();
		}
		PartnerAccount partnerAccount = partnerAccountMapper.selectByPartnerId(reqdata.getPartnerid());
		PartnerGivenFieldDto partnerGivenFieldDto = new PartnerGivenFieldDto();
		BeanUtils.copyProperties(partnerAccount, partnerGivenFieldDto);
		Partner partner = new Partner().selectById(partnerGivenFieldDto.getPartnerid());
		partnerGivenFieldDto.setPhone(partner.getPhone());
		PartnerBankcard partnerBankcard = partnerBankcardMapper.getValidCard(reqdata.getPartnerid());
		if (null != partnerBankcard) {
			if (StringUtil.isNotEmpty(partnerBankcard.getBankname())) {
				partnerGivenFieldDto.setBankname(partnerBankcard.getBankname());
			}
			if (StringUtil.isNotEmpty(partnerBankcard.getAcctno())) {
				partnerGivenFieldDto.setAcctno(partnerBankcard.getAcctno());
			}
		}
		BusinessManager businessManager = new BusinessManager().selectById(partnerAccount.getBusinessManagerId());
		if (businessManager != null) {
			partnerGivenFieldDto.setBusinessManagerId(businessManager.getBusinessManagerId());
			partnerGivenFieldDto.setBusinessManager(businessManager.getBusinessManager());
			partnerGivenFieldDto.setNickname(businessManager.getNickname());
			partnerGivenFieldDto.setBusinessEmail(businessManager.getEmail());
			partnerGivenFieldDto.setBusinessPhone(businessManager.getPhone());
		}
		return smartResult(partnerGivenFieldDto);
	}

	public SmartResult getRecommendCompanyList(BaseSimpleFormBean<RecommendCompanyListFormBean> formBean) {
		RecommendCompanyListFormBean reqdata = formBean.getReqdata();
		if (reqdata == null) return errorParamSmartResult();

		String company = reqdata.getCompany();
		int partnerType = reqdata.getPartnerType();
		int state = reqdata.getState();

		Page page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		partnerRecommendCompanyMapper.getRecommendList(company, state, partnerType);

		return smartResultPage(page);
	}

	public SmartResult verifyRecommendCompany(BaseSimpleFormBean<VerifyRecommendCompanyFormBean> formBean) {
		VerifyRecommendCompanyFormBean reqdata = formBean.getReqdata();
		if (reqdata == null) return errorParamSmartResult();

		PartnerRecommendCompany recommendCompany = new PartnerRecommendCompany().selectById(reqdata.getId());
		if (recommendCompany == null) return errorParamSmartResult();
		if (recommendCompany.getState() >= Constants.PARTNER_RECOMMEND_VERIFIED) return smartResult(StatusMsg.StatusMsg_507);

		if (1 == reqdata.getFlag()) {
			Company company = new Company().selectById(reqdata.getActualCompanyid());
			if (company == null) return smartResult(StatusMsg.StatusMsg_302);
			BeanUtils.copyProperties(reqdata, recommendCompany);
			recommendCompany.setState(Constants.PARTNER_RECOMMEND_VERIFIED);
		} else {
			recommendCompany.setReason(reqdata.getReason());
			recommendCompany.setState(Constants.PARTNER_RECOMMEND_REJECT);
		}

		wxPartnerMessageService.notifyPartnerCompanyVerify(recommendCompany);
		if (recommendCompany.updateById()) {
			return smartResult();
		}
		return optFailSmartResult();
	}

	public SmartResult handleRecommendCompany(BaseSimpleFormBean<VerifyRecommendCompanyFormBean> formBean) {
		VerifyRecommendCompanyFormBean reqdata = formBean.getReqdata();
		if (reqdata == null) return errorParamSmartResult();

		PartnerRecommendCompany recommendCompany = new PartnerRecommendCompany().selectById(reqdata.getId());
		if (recommendCompany == null) return errorParamSmartResult();
		if (recommendCompany.getState() >= Constants.PARTNER_RECOMMEND_HANDLED) return smartResult(StatusMsg.StatusMsg_508);

		Company company = new Company().selectById(reqdata.getActualCompanyid());
		if (company == null) return smartResult(StatusMsg.StatusMsg_302);

		Integer compid = company.getCompid();
		Integer partnerid = recommendCompany.getPartnerid();
		Asserts.notTrue(partnerCompanyMapper.existsByPartneridAndCompid(partnerid, compid, reqdata.getActualPartnerType()),
				StatusMsg.StatusMsg_509);

		LocalDate localDate = DateUtil.date2LocalDate(new Date()).plusYears(1).minusDays(1);
		PartnerCompany partnerCompany = new PartnerCompany().setCompid(compid)
				.setExpiredate(DateUtil.localDate2Date(localDate))
				.setPartnerid(partnerid)
				.setRatio(reqdata.getActualBrokerageRatio())
				.setType(reqdata.getActualPartnerType())
				.setSettleType(reqdata.getSettleType());

		if (partnerCompany.insert()) {
			recommendCompany.setActualCompanyid(reqdata.getActualCompanyid())
					.setActualBrokerageRatio(reqdata.getActualBrokerageRatio())
					.setActualPartnerType(reqdata.getActualPartnerType())
					.setState(Constants.PARTNER_RECOMMEND_HANDLED);

			wxPartnerMessageService.notifyPartnerCompanyVerify(recommendCompany);

			if (recommendCompany.updateById()) {
				return smartResult();
			}
		}
		return optFailSmartResult();
	}

	/**
	 * 后台添加合伙人,如果该手机号已经存在合伙人，则更新
	 *
	 * @param formBean
	 * @return
	 */
	public SmartResult savePartner(BaseSimpleFormBean<SavePartnerFormBean> formBean) {
		SavePartnerFormBean reqdata = formBean.getReqdata();
		if (reqdata == null) return errorParamSmartResult();

		Partner partner = partnerMapper.checkPartnerExistByPhone(reqdata.getPhone());
		int partnerType = reqdata.getPartnerType();
		if (partner == null) {
			partner = new Partner();
			partner.setPhone(reqdata.getPhone());
			partner.setRegfrom(2);
			partner.setState(2);
			// 后台创建机构合伙人,设置登陆密码
			String loginname = reqdata.getLoginname();
			if (partnerType == Constants.PARTNER_ACCOUNT_TYPE_ORGAN && StringUtil.isNotEmpty(loginname)) {

				if (StringUtil.isEmpty(reqdata.getPassword())) {
					return SmartResult.fail(StatusMsg.StatusMsg_130);
				}

				if (partnerMapper.existsLoginname(loginname) > 0) {
					return SmartResult.fail(StatusMsg.StatusMsg_131);
				}

				String salt = RandomUtil.generateString(8);
				partner.setLoginname(loginname);
				partner.setPassword(MD5Util.md5(reqdata.getPassword() + salt));
				partner.setSalt(salt);
			}
			if (!partner.insert()) {
				return smartResult(StatusMsg.StatusMsg_199);
			}
		} else {
			return smartResult(StatusMsg.StatusMsg_515);
		}

		//

		Integer partnerid = partner.getPartnerid();
		PartnerAccount partnerAccount = new PartnerAccount();
		BeanUtils.copyProperties(reqdata, partnerAccount);
		partnerAccount.setPromoCode(String.valueOf(partnerid + 100));
		partnerAccount.setPartnerid(partnerid);
		partnerAccount.setRealnameAuth(4);
		partnerAccount.setEffectivedate(new Date());
		Calendar curr = Calendar.getInstance();
		curr.add(Calendar.YEAR, 1);
		curr.add(Calendar.DATE, -1);
		Date expiredate = curr.getTime();
		partnerAccount.setExpiredate(expiredate);

		// 提现模式默认设置为2
		partnerAccount.setRemitType(RemitType.OFFLINE);

		if (!partnerAccount.insert()) {
			return smartResult(StatusMsg.StatusMsg_199);
		}

		//关联CRM意向合伙人，根据名称去 CRM里查询是否有意向合伙人，如果有的话，绑定意向合伙人并将意向合伙人转为已注册
		//可能会查到多条
		List<IntentionPartner> intentionPartnerList = intentionPartnerMapper.getIntentionPartnerByName(partnerAccount.getRealname());
		if (null != intentionPartnerList && intentionPartnerList.size() > 0) {
			//当只查到一条的时候进行操作，如果查到多条，需要去CRM手动关联
			if (1 == intentionPartnerList.size()) {
				IntentionPartner intentionPartner = intentionPartnerList.get(0);
				intentionPartner.setFlag(2);
				intentionPartner.setZddPartnerId(partnerAccount.getPartnerid());
				if (!intentionPartner.updateById()) {
					return optFailSmartResult();
				}
				//将意向合伙人中的数据带到实名表里面
				partnerAccount.setIntentionPartnerId(intentionPartner.getId());
				partnerAccount.setDevelopAbility(intentionPartner.getDevelopAbility());
				partnerAccount.setPotential(intentionPartner.getPotential());
				partnerAccount.setSource(intentionPartner.getPartnerSource());
				partnerAccount.setPartnerType(intentionPartner.getPartnerType());
				partnerAccount.setRemarks(intentionPartner.getRemarks());
				if (!partnerAccount.updateById()) {
					return optFailSmartResult();
				}
			}
		}

		//修改银行卡
		PartnerBankcard bankcard = partnerBankcardMapper.getValidCard(partnerid);
		if (bankcard == null) {
			bankcard = new PartnerBankcard().setPartnerid(partnerid).setState(1);
		}
		bankcard.setPayername(reqdata.getPayername())
				.setIdno(reqdata.getAcctIdno())
				.setAcctno(reqdata.getAcctno())
				.setBankname(reqdata.getBankname())
				.setIdno(reqdata.getIdno())
				.setTelephone(reqdata.getAcctphone());

		if (bankcard.insertOrUpdate()) {
			return smartResult();
		}
		return optFailSmartResult();
	}

	public void performanceNotice() {

		LogUtil.info("合伙人绩效通知--");
		//注册一个星期，欢迎提示
		LocalDate now = LocalDate.now();
		LocalDate lastWeekLocalDate = now.minusWeeks(1);
		partnerMapper.getPartnerDetailByEffectivedate(DateUtil.localDate2Date(lastWeekLocalDate)).forEach(partner -> {
			try {
				wxPartnerMessageService.sendWelcomeNotice(partner);
			} catch (Exception ignored) {}
		});

		partnerMapper.getAllValidPartner().forEach(partner -> {
			try {
				Integer partnerid = partner.getPartnerid();
				Date effectivedate = partner.getEffectivedate();
				Date nowDate = DateUtil.localDate2Date(now);
				int days = DateUtil.getIntervalDays(effectivedate, nowDate);
				if (days <= 0) {
					//如果是今天刚注册的，直接返回
					return;
				}
				int currSeasonDays = days % 90;
				//这个季度推荐的数量
				Date currSeasonStart = DateUtil.localDate2Date(now.minusDays(currSeasonDays));
				Date yesterday = DateUtil.getYesterday();
				int currSeasonCount = partnerCompanyMapper.countPartnerCompanyByDate(partnerid, currSeasonStart, yesterday);
				//上个季度推荐的数量
				Date lastSeasonStart = DateUtil.localDate2Date(now.minusDays(90 + currSeasonDays));
				Date lastSeasonEnd = DateUtil.localDate2Date(now.minusDays(currSeasonDays + 1));
				int lastSeasonCount = partnerCompanyMapper.countPartnerCompanyByDate(partnerid, lastSeasonStart, lastSeasonEnd);
				//更新成功推荐企业的数量
				new PartnerAccount().setAcctid(partner.getAcctid())
						.setCurrSeasonCount(currSeasonCount)
						.setLastSeasonCount(lastSeasonCount)
						.updateById();

				if (currSeasonDays == 0) {
					//如果currSeasonDays=0，表示正好是第90天季度结束，今天是新的季度的第一天
					if (lastSeasonCount == 0 && days >= 90) {
						LogUtil.info("正好过90天的合伙人：" + partner.getRealname());
						//过去三个月都没有推荐成功的，发送模板消息
						wxPartnerMessageService.sendPerformanceNotice(partner, 3, 0);
						wxMessageService.sendPerformanceNotice(partner, 3);
					}
				} else if (currSeasonDays == 60) {
					//正好新季度60天结束。
					LogUtil.info("正好过60天的合伙人：" + partner.getRealname());
					if (currSeasonCount == 0) {
						wxPartnerMessageService.sendPerformanceNotice(partner, 2, 0);
					}
				} else if (currSeasonDays == 30) {
					//正好新季度30天结束。
					LogUtil.info("正好过30天的合伙人：" + partner.getRealname());
					wxPartnerMessageService.sendPerformanceNotice(partner, 1, currSeasonCount);
				}
			} catch (Exception ignored) {}

		});
	}

	public SmartResult partnerRescission(BaseSimpleFormBean<Integer> formBean) {
		Integer partnerid = formBean.getReqdata();
		Partner partner = new Partner().selectById(partnerid);
		if (null == partner) {
			return smartResult(StatusMsg.StatusMsg_501);
		}
		partner.setRescissionMode(RescissionMode.MANUAL)
				.setRescissionAdminId(formBean.getUserid())
				.setRescissionTime(new Date())
				.setState(Constants.partner_state_4);
		if (!partner.updateById()) {
			return smartResult(StatusMsg.StatusMsg_199);
		}
		return smartResult();
	}

	public SmartResult partnerRenew(BaseSimpleFormBean<PartnerRenewFormbean> formBean) {
		@Valid PartnerRenewFormbean reqdata = formBean.getReqdata();
		int partnerid = reqdata.getPartnerid();
		@Range(min = 1, max = 2) int year = reqdata.getYear();

		Partner partner = new Partner().selectById(partnerid);
		PartnerAccount account = new PartnerAccount().selectOne(Condition.create().eq("partnerid", partnerid));
		if (partner == null || account == null) return SmartResult.fail(StatusMsg.StatusMsg_501);

		Integer state = partner.getState();

		Date newEffectiveDate = null;
		Date newExpireDate = null;
		if (state == Constants.partner_state_2) {
			// 未过期的和已经过期的，续约开始日期接着之前的日期
			Date expiredate = account.getExpiredate();
			newEffectiveDate = DateUtil.addDay(expiredate, 1);
			newExpireDate = DateUtil.addYear(expiredate, year);
		} else if (state == Constants.partner_state_4) {
			// 解约的，续约开始日期按当日
			newEffectiveDate = DateUtil.nowDate();
			newExpireDate = DateUtil.addDay(DateUtil.addYear(newEffectiveDate, year), -1);
		} else {
			return SmartResult.fail(StatusMsg.StatusMsg_504);
		}

		partner.setState(Constants.partner_state_2).updateById();
		account.setEffectivedate(newEffectiveDate).setExpiredate(newExpireDate).updateById();
		new PartnerValidity().setPartnerid(partnerid).setEffectivedate(newEffectiveDate).setExpiredate(newExpireDate).insert();

		//结果通知创客
		wxPartnerMessageService.partnerRenew(account.getAcctid());

		//通知商务经理
		String info = "合伙人-" + account.getRealname() + "已成功续约，到期日期为" + DateUtil.getString(newExpireDate, DateUtil.FORMAT_STYLE_3);
		new Thread(() -> commonService.sendEnterpriseWeChatNotice(account.getBusinessManagerId(), account.getRealname(), 1, info)).start();

		return SmartResult.success();
	}

	/**
	 * 获取解约合伙人列表
	 *
	 * @param formBean
	 * @return
	 */
	public SmartResult getRescissionList(BaseSimpleFormBean<PartnerListFormBean> formBean) {
		PartnerListFormBean reqdata = formBean.getReqdata();
		if (reqdata == null) return errorParamSmartResult();
		String inviter = reqdata.getInviter();
		String name = reqdata.getName();
		String businessManager = reqdata.getBusinessManager();
		Page<Object> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		List<PartnerBriefDto> list = partnerAccountMapper.getRescissionList(inviter, name, businessManager);
		structurePartnerData(list, 0);
		return smartResult(list, page.getTotal(), page.getPages(), page.getPageNum());
	}

	public SmartResult<PartnerSubDto> getSubPartnerList(BaseSimpleFormBean<SubPartnerListFormBean> formBean) {
		@Valid SubPartnerListFormBean reqdata = formBean.getReqdata();
		if (reqdata == null) return errorParamSmartResult();

		int partnerid = reqdata.getPartnerid();

		List<PartnerSubDto> list = partnerSubMapper.findSubListByUpId(partnerid);
		return smartResult(list);
	}

	public SmartResult addEditSubPartner(BaseSimpleFormBean<AddEditSubPartnerFormBean> formBean) {
		@Valid AddEditSubPartnerFormBean reqdata = formBean.getReqdata();
		if (reqdata == null) return errorParamSmartResult();

		int id = reqdata.getId();
		int partnerid = reqdata.getPartnerid();
		int subPartnerid = reqdata.getSubPartnerid();
		BigDecimal rate = reqdata.getRate();

		PartnerDetailDto partner = partnerMapper.getPartnerDetail(partnerid);
		PartnerDetailDto subPartner = partnerMapper.getPartnerDetail(subPartnerid);
		if (partner == null || partner.getState() != Constants.partner_state_2 || partner.getRealnameAuth() != Constants.partner_auth_4 ||
				subPartner == null || subPartner.getState() != Constants.partner_state_2 ||
				subPartner.getRealnameAuth() != Constants.partner_auth_4) {
			return smartResult(StatusMsg.StatusMsg_501);
		}

		if (id == 0) {
			PartnerSub partnerSub = new PartnerSub();

			//检查重复绑定
			PartnerSubDto exist = partnerSubMapper.findUpPartnerBySubId(subPartnerid);
			if (exist != null) return smartResult(StatusMsg.StatusMsg_516);

			//检查循环绑定:  防止A->B->A的情况
			PartnerSubDto exist2 = partnerSubMapper.findByUpIdAndSubId(subPartnerid, partnerid);
			if (exist2 != null) return SmartResult.fail(StatusMsg.StatusMsg_517);

			partnerSub.setPartnerid(partnerid).setSubPartnerid(subPartnerid).setRate(rate).setManagerid(formBean.getUserid());

			if (partnerSub.insert()) {
				//发送模板消息给上级合伙人
				wxPartnerMessageService.noticeSubPartnerAdded(partnerSubMapper.findById(partnerSub.getId()));

				return SmartResult.success(partnerSub.getId());
			}
		} else {
			PartnerSub partnerSub = new PartnerSub().selectById(id);
			if (partnerSub == null) return errorParamSmartResult();

			partnerSub.setPartnerid(partnerid).setSubPartnerid(subPartnerid).setRate(rate).setManagerid(formBean.getUserid());
			if (partnerSub.updateById()) return SmartResult.success(partnerSub.getId());
		}
		return optFailSmartResult();
	}

	public SmartResult delSubPartner(BaseSimpleFormBean<Integer> formBean) {
		@Valid Integer id = formBean.getReqdata();
		new PartnerSub().deleteById(id);
		return smartResult();
	}

	public SmartResult getValidSubPartnerList(BaseSimpleFormBean<String> formBean) {
		@Valid String name = formBean.getReqdata();
		List<PartnerNameDto> list = partnerMapper.findValidSubPartnerList(name);
		return smartResult(list);
	}

	public void checkPartnerKpiPerformance() {
		Date lastMonthBeginDate = DateUtil.getLastMonthBeginDate();
		Date lastMonthEndDate = DateUtil.getLastMonthEndDate();
		Date quarterBeginDate = DateUtil.getQuarterBeginDate(lastMonthBeginDate);
		Date quarterEndDate = DateUtil.getQuarterEndDate(lastMonthBeginDate);

		// 当前要计算的季度的比例
		// +1, 计算总天数
		int totalDays = DateUtil.getIntervalDays(quarterBeginDate, quarterEndDate) + 1;
		int currDays = DateUtil.getIntervalDays(quarterBeginDate, lastMonthEndDate) + 1;
		float kpiRate = NumberUtil.formatFloatRound(currDays * 1.0f / totalDays, 4, RoundingMode.DOWN);

		partnerMapper.getAllValidPartner().forEach(partner -> {
			try {
				PartnerKpiDataVO kpiData = getPartnerKpiData(partner.getPartnerid(), lastMonthBeginDate);
				if (kpiData == null) return;

				// 发送消息
				StringBuilder succ = new StringBuilder();
				StringBuilder fail = new StringBuilder();

				// 注册企业 (完成注册及审核（根据企业注册时填写的邀请码）)
				int compRegiKpi = kpiData.getCompRegiKpi();
				int compRegi = kpiData.getCompRegi();
				String regi = "本季度注册企业完成" + compRegi + "个";
				if (compRegi >= compRegiKpi) {
					succ.append(regi);
				} else {
					fail.append(regi);
				}
				// 邀请企业(填写申请推荐数)
				int invitationCompKpi = kpiData.getInvitationCompKpi();
				int invitationComp = kpiData.getInvitationComp();
				String invite = "邀请企业完成" + invitationComp + "个";
				if (invitationComp >= invitationCompKpi) {
					if (succ.length() > 0) succ.append("，");
					succ.append(invite);
				} else {
					if (fail.length() > 0) fail.append("，");
					fail.append(invite);
				}
				/*// 新增二级合伙人(推荐合伙人注册数)
				int newlySecondPartKpi = kpiData.getNewlySecondPartKpi();
				int newlySecondPart = kpiData.getNewlySecondPart();
				String secondPart = "上月新增二级合伙人" + newlySecondPart +"个";
				if (newlySecondPart >= newlySecondPartKpi) {
					if (succ.length() > 0) succ.append("，");
					succ.append(secondPart);
				} else {
					if (fail.length() > 0) fail.append("，");
					fail.append(secondPart);
				}
				// 企业交易额(自己关联企业代付金额总数)
				BigDecimal compDealKpi = kpiData.getCompDealKpi();
				BigDecimal compDeal = kpiData.getCompDeal();
				String deal = "企业交易额" + compDeal.setScale(2, BigDecimal.ROUND_DOWN).toString() + "元";
				float dealRate = compDeal.divide(compDealKpi, 4, BigDecimal.ROUND_DOWN).floatValue();
				if (dealRate >= kpiRate) {
					if (succ.length() > 0) succ.append("，");
					succ.append(deal);
				} else {
					if (fail.length() > 0) fail.append("，");
					fail.append(deal);
				}*/
				// 交易企业数(自己关联企业发送交易)
				int compDealNumKpi = kpiData.getCompDealNumKpi();
				int compDealNum = kpiData.getCompDealNum();
				String dealNum = "交易企业数" + compDealNum;
				float dealNumRate = NumberUtil.formatFloatRound(compDealNum * 1.0f / compDealNumKpi, 4, RoundingMode.DOWN);
				if (dealNumRate >= kpiRate) {
					if (succ.length() > 0) succ.append("，");
					succ.append(dealNum);
				} else {
					if (fail.length() > 0) fail.append("，");
					fail.append(dealNum);
				}

				// 合并
				StringBuilder sb = new StringBuilder();
				if (succ.length() > 0) {
					sb.append("恭喜您：").append(succ);
				}
				if (fail.length() > 0) {
					if (sb.length() > 0) {
						sb.append("；另外");
					}
					sb.append(fail).append("，要加油咯");
				}
				sb.append("。");

				wxPartnerMessageService.notifyPartnerKpi(partner, sb.toString());
				log.info("合伙人绩效通知:partnerId = {}, name = {}, 绩效 = {}", partner.getPartnerid(), partner.getRealname(), sb.toString());
			} catch (Exception e) {
				log.info("查询合伙人绩效报错:partnerid = {} ", partner.getPartnerid(), e);
			}
		});
	}

	/**
	 * @param partnerid
	 * @param month     需要统计的月份日期. 当月任何一天的日期均可.
	 * @return
	 */
	public PartnerKpiDataVO getPartnerKpiData(int partnerid, Date month) {
		PartnerKpiDto partnerKpi = crmKpiMapper.getPartnerKpi(partnerid);
		if (partnerKpi == null) return null;

		PartnerKpiDataVO dataVO = PartnerKpiDataVO.of(partnerKpi);

		// 注册企业 (完成注册及审核（根据企业注册时填写的邀请码）)
		int countPartnerInvited = companyMapper.countPartnerInvited(partnerid, month);
		dataVO.setCompRegi(countPartnerInvited);

		// 邀请企业(填写申请推荐数)
		int countPartnerCompany = partnerCompanyMapper.countPartnerCompanyByQuarter(partnerid, month);
		dataVO.setInvitationComp(countPartnerCompany);

/*      // 新增二级合伙人(推荐合伙人注册数)
		int countSubPartner = partnerSubMapper.countSubPartnerByMonth(partnerid, month);
		dataVO.setNewlySecondPart(countSubPartner);

		// 企业交易额(自己关联企业代付金额总数)
		BigDecimal totalAmount = quarterTotalAmountByPartner(companyIds, month);
		dataVO.setCompDeal(totalAmount);
*/
		// 交易企业数(自己关联企业发送交易)
		List<Integer> companyIds = partnerCompanyMapper.getPartnerCompanyIds(partnerid);
		int countTradeCompany = quarterCountTradeCompany(companyIds, month);
		dataVO.setCompDealNum(countTradeCompany);

		return dataVO;
	}

	private BigDecimal quarterTotalAmountByPartner(List<Integer> companyIds, Date month) {
		String ids = StringUtils.join(companyIds, ",");
		BigDecimal quarterTotalAmount = companyProjectMapper.getquarterTotalAmountByCompids(ids, month);
		// BigDecimal quarterCrowdsourceAmount = crowdsourceProjectMapper.getQuarterTotalAmountByCompids(ids, month);
		// return quarterCrowdsourceAmount.add(quarterTotalAmount);
		return quarterTotalAmount;
	}

	private int quarterCountTradeCompany(List<Integer> companyIds, Date month) {
		String ids = StringUtils.join(companyIds, ",");
		List<Integer> list1 = companyProjectMapper.getTradeCompanyByCompids(ids, month);
		// List<Integer> list2 = crowdsourceProjectMapper.getTradeCompanyByCompids(ids, month);

		// 取并集
		// list1.removeAll(list2);
		// list1.addAll(list2);
		return list1.size();
	}

	public SmartResult<WriteOffBrokerageVO> writeOffCrowdsourcePartnerBrokerage(
			BaseSimpleFormBean<List<WriteOffCrowdsourcePartnerBrokerageFormBean>> formBean) {

		@Valid List<WriteOffCrowdsourcePartnerBrokerageFormBean> list = formBean.getReqdata();
		if (CollectionUtils.isEmpty(list)) return errorParamSmartResult();

		List<Integer> stateErrorList = new ArrayList<>();
		List<Integer> idList = list.stream().map(WriteOffCrowdsourcePartnerBrokerageFormBean::getBrokerageid).collect(Collectors.toList());

		for (Integer id : idList) {
			CommissionRecordDto record = partnerBrokerageMapper.getCommissionRecord(id);
			if (record == null) {
				stateErrorList.add(id);
				continue;
			}
			PartnerAccount account = partnerAccountMapper.getPartnerAccountByPartnerId(record.getPartnerid());
			if (account == null) {
				stateErrorList.add(id);
				continue;
			}

			if (record.getState() != PartnerBrokerageState.SETTLED) {
				stateErrorList.add(id);
			}
		}

		if (!CollectionUtils.isEmpty(stateErrorList)) {
			WriteOffBrokerageVO vo = new WriteOffBrokerageVO(null, stateErrorList);
			return SmartResult.of(vo, StatusMsg.StatusMsg_101);
		}

		for (WriteOffCrowdsourcePartnerBrokerageFormBean bean : list) {
			PartnerBrokerage partnerBrokerage = new PartnerBrokerage().selectById(bean.getBrokerageid());
			partnerBrokerage.setBrokerageid(bean.getBrokerageid())
					.setState(PartnerBrokerageState.WITHDRAWED)
					.setRemitType(RemitType.OFFLINE)
					.setBrokerage(bean.getAmount())
					.updateById();
			coreBrokerageService.recordPartnerAccountFlowAndNotice(partnerBrokerage, "智众包项目手动销账");
		}
		return SmartResult.success();
	}

	public SmartResult<WriteOffBrokerageVO> writeOffOrgPartnerBrokerage(BaseSimpleFormBean<WriteOffPartnerBrokerageFormBean> formBean) {
		if (null == formBean || null == formBean.getReqdata()) {
			return errorParamSmartResult();
		}
		@Valid String ids = formBean.getReqdata().getIds();
		String path = formBean.getReqdata().getVoucherPath();
		if (StringUtil.isEmpty(ids)) return errorParamSmartResult();

		List<Integer> notOrgPartnerList = Lists.newArrayList();
		List<Integer> stateErrorList = new ArrayList<>();
		List<Integer> idList = Stream.of(StringUtils.split(ids, ",")).map(StringUtil::toInt).distinct().collect(Collectors.toList());

		for (Integer id : idList) {
			CommissionRecordDto record = partnerBrokerageMapper.getCommissionRecord(id);
			if (record == null) {
				stateErrorList.add(id);
				continue;
			}
			PartnerAccount account = partnerAccountMapper.getPartnerAccountByPartnerId(record.getPartnerid());
			if (account == null) {
				stateErrorList.add(id);
				continue;
			}

			if (record.getState() != PartnerBrokerageState.SETTLED) {
				stateErrorList.add(id);
			}

			// 如果只有机构合伙人,或者工作室模式提现,或者众包项目佣金,才能提现
			if (!(NumberUtil.equals(account.getPartnerType(), Constants.PARTNER_ACCOUNT_TYPE_ORGAN) ||
					      NumberUtil.equals(account.getRemitType(), RemitType.OFFLINE) ||
					      record.getPartnerType() == PartnerBrokerageType.CROWDSOURCE)) {
				notOrgPartnerList.add(id);
			}
		}

		if (!CollectionUtils.isEmpty(notOrgPartnerList) || !CollectionUtils.isEmpty(stateErrorList)) {
			WriteOffBrokerageVO vo = new WriteOffBrokerageVO(notOrgPartnerList, stateErrorList);
			return SmartResult.of(vo, StatusMsg.StatusMsg_101);
		}

		boolean update = new PartnerBrokerage().setState(PartnerBrokerageState.WITHDRAWED)
				.setRemitType(RemitType.OFFLINE)
				.setVoucherPath(path)
				.setAdminid(formBean.getUserid())
				.update(Condition.create().in("brokerageid", idList));
		if (update) return smartResult();
		return optFailSmartResult();
	}

	public SmartResult<PartnerBriefDto> listBrokerageExceedPartners(BaseSimpleFormBean<PartnerListFormBean> formBean) {
		PartnerListFormBean reqdata = formBean.getReqdata();
		if (reqdata == null) return errorParamSmartResult();
		String inviter = reqdata.getInviter();
		String name = reqdata.getName();
		String businessManager = reqdata.getBusinessManager();

		// 限额
		int amount = 8000;
		Date date = DateUtil.addMonth(DateUtil.nowDate(), -1);
		Page<Object> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		List<PartnerBriefDto> list = partnerAccountMapper.listBrokerageExceedPartners(inviter, name, businessManager, date, amount);
		structurePartnerData(list, 4);
		return smartResult(list, page.getTotal(), page.getPages(), page.getPageNum());
	}

	public SmartResult setPartnerBrokerageRemitType(BaseSimpleFormBean<PartnerRemitTypeFormBean> formBean) {
		@Valid PartnerRemitTypeFormBean reqdata = formBean.getReqdata();
		int remitType = reqdata.getRemitType();
		List<Integer> idList =
				Stream.of(reqdata.getPartnerids().split(",")).map(StringUtil::toInt).distinct().collect(Collectors.toList());
		if (remitType == RemitType.ONLINE) {
			new PartnerAccount().setRemitType(remitType).update(Condition.create().in("partnerid", idList));
		} else if (remitType == RemitType.OFFLINE) {
			idList.forEach(partnerid -> {
				PartnerAccount account = new PartnerAccount().selectOne(Condition.create().eq("partnerid", partnerid));
				account.setRemitType(remitType).updateById();

				if (NumberUtil.safeInt(account.getStudioId()) == 0) {
					//未绑定工作室,通知合伙人的商务经理
					String finalInfo = "合伙人:"+account.getRealname()+" 提现模式已设置为工作室模式,请联系合伙人注册工作室";
					new Thread(() -> commonService.sendEnterpriseWeChatNotice(account.getBusinessManagerId(), null, 1, finalInfo)
					).start();
				}
			});
		}
		return SmartResult.success();
	}

	public SmartResult<PartnerExpireDto> listPendingExpirePartners(BaseSimpleFormBean<PartnerListFormBean> formBean) {

		@Valid PartnerListFormBean reqdata = formBean.getReqdata();
		String name = reqdata.getName();
		String inviter = reqdata.getInviter();
		String businessManager = reqdata.getBusinessManager();

		Date expiredate = DateUtil.addMonth(DateUtil.nowDate(), 1);
		Page<PartnerExpireDto> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		partnerAccountMapper.getPendingExpirePartnerList(inviter, name, businessManager, expiredate).forEach(pe -> {
			int partnerid = pe.getPartnerid();
			Date peExpiredate = pe.getExpiredate();
			Date startdate = DateUtil.addYear(peExpiredate, -1);
			List<Integer> compids = partnerCompanyMapper.getPartnerCompanyIdsByDate(partnerid, startdate, peExpiredate);
			int comanyCount = 0;
			BigDecimal totalAmount = BigDecimal.ZERO;
			if (!CollectionUtils.isEmpty(compids)) {
				comanyCount = compids.size();
				String ids = StringUtils.join(compids, ",");
				totalAmount = companyProjectMapper.getTotalAmountByCompids(ids, startdate, peExpiredate);
			}
			//计算未提现金额
			BigDecimal unremitBrokerage = partnerBrokerageMapper.getTotalBrokerageWithState(partnerid, PartnerBrokerageState.SETTLED);
			pe.setNoCash(unremitBrokerage);
			//计算已提现金额
			BigDecimal remitBrokerage = partnerBrokerageMapper.getTotalBrokerageWithState(partnerid, PartnerBrokerageState.WITHDRAWED);
			pe.setHasBeenProposed(remitBrokerage);

			pe.setLastYearCompanyCount(comanyCount).setTotalCompanyTradeAmount(totalAmount);
		});

		return SmartResult.ofPage(page);
	}

	public void checkAndHandlePartnerExpired() {
		Date nowDate = DateUtil.nowDate();
		List<PartnerExpireDto> list = partnerAccountMapper.getPendingExpirePartnerList(null, null, null, nowDate);

		for (PartnerExpireDto dto : list) {
			new Partner().setPartnerid(dto.getPartnerid())
					.setRescissionMode(RescissionMode.AUTO)
					.setRescissionTime(new Date())
					.setState(Constants.partner_state_4)
					.updateById();
		}
	}

	public void checkPartnerBrokerageMonthExceed() {
		int amount = 8000;
		List<PartnerMonthBrokerageDto> list = partnerBrokerageMapper.listBrokerageMonthExceed(DateUtil.getStartDayOfMonth(new Date()),
				amount);
		if (!CollectionUtils.isEmpty(list)) {
			String names = list.stream().map(PartnerMonthBrokerageDto::getPartnerName).collect(Collectors.joining("，"));
			String info = "本月以下合伙人的佣金已经超过" + amount + "元:\n" + names;
			commonService.sendEnterpriseWeChatNotice(0, "胡刚", 2, info);
		}
	}

	public SmartResult<PartnerCompanyExpireDto> listPendingExpirePartnerCompany(BaseSimpleFormBean formBean) {

		Page<PartnerCompanyExpireDto> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		List<PartnerCompanyExpireDto> list = partnerCompanyMapper.listPendingExpired(DateUtil.addMonth(DateUtil.nowDate(), 1));

		for (PartnerCompanyExpireDto dto : list) {
			BigDecimal totalAmount = coreProjectService.getTotalAmountByCompids(String.valueOf(dto.getCompid()), dto.getCreatetime(),
					dto.getExpiredate());
			dto.setTotalAmount(totalAmount);
		}

		return SmartResult.ofPage(page);
	}

	public SmartResult<PartnerCompanyExpireDto> listExpiredPartnerCompany(BaseSimpleFormBean<ListPartnerExpiredFormBean> formBean) {
		@Valid ListPartnerExpiredFormBean reqdata = formBean.getReqdata();
		Page<PartnerCompanyExpireDto> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		partnerCompanyMapper.listExpired(reqdata.getName(), reqdata.getState(), reqdata.getExpired(), reqdata.getStartDate(),
				reqdata.getEndDate());

		for (PartnerCompanyExpireDto dto : page.getResult()) {
			BigDecimal totalAmount = coreProjectService.getTotalAmountByCompids(String.valueOf(dto.getCompid()), dto.getCreatetime(),
					dto.getExpiredate());
			dto.setTotalAmount(totalAmount);
		}
		return SmartResult.ofPage(page);
	}

	public SmartResult<PartnerMakerExpireDto> listPendingExpirePartnerMaker(BaseSimpleFormBean formBean) {

		Page<PartnerMakerExpireDto> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		List<PartnerMakerExpireDto> list = partnerMakerMapper.listPendingExpired(DateUtil.addMonth(DateUtil.nowDate(), 1));

		for (PartnerMakerExpireDto dto : list) {
			BigDecimal totalAmount = coreProjectService.getTotalAmountByUserid(dto.getUserid(), dto.getCreatetime(), dto.getExpiredate());
			dto.setTotalAmount(totalAmount);
		}

		return SmartResult.ofPage(page);
	}

	public SmartResult<PartnerMakerExpireDto> listExpiredPartnerMaker(BaseSimpleFormBean<ListPartnerExpiredFormBean> formBean) {
		@Valid ListPartnerExpiredFormBean reqdata = formBean.getReqdata();
		Page<PartnerMakerExpireDto> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		partnerMakerMapper.listExpired(reqdata.getName(), reqdata.getState(), reqdata.getExpired(), reqdata.getStartDate(),
				reqdata.getEndDate());

		for (PartnerMakerExpireDto dto : page.getResult()) {
			BigDecimal totalAmount = coreProjectService.getTotalAmountByUserid(dto.getUserid(), dto.getCreatetime(), dto.getExpiredate());
			dto.setTotalAmount(totalAmount);
		}
		return SmartResult.ofPage(page);
	}

	public SmartResult savePartnerCompanyState(BaseSimpleFormBean<SavePartnerCompanyStateFormBean> formBean) {
		@Valid SavePartnerCompanyStateFormBean reqdata = formBean.getReqdata();
		new PartnerCompany().setId(reqdata.getId()).setState(reqdata.getState()).updateById();
		return SmartResult.success();
	}

	public SmartResult savePartnerMakerState(BaseSimpleFormBean<SavePartnerCompanyStateFormBean> formBean) {
		@Valid SavePartnerCompanyStateFormBean reqdata = formBean.getReqdata();
		new PartnerMaker().setId(reqdata.getId()).setState(reqdata.getState()).updateById();
		return SmartResult.success();
	}

	public SmartResult fixExpiredPartnerProjectBrokerage(String ids) {
		List<Integer> idList = StringUtil.splitToInt(ids, ",");
		for (Integer id : idList) {
			try {
				PartnerCompany partnerCompany = new PartnerCompany().selectById(id);
				if (partnerCompany == null) continue;

				Integer compid = partnerCompany.getCompid();
				Date expiredate = partnerCompany.getExpiredate();
				Integer partnerid = partnerCompany.getPartnerid();
				List<CompanyProject> projects = companyProjectMapper.listProjectByCompidAndStartDate(compid, expiredate);
				log.info("---------------------------||||||||||-------------------------");
				log.info("id = {}, compid = {}, partnerid = {}, expiredate = {}, projects count = {}", id, compid, partnerid, expiredate,
						projects.size());

				if (org.apache.commons.collections4.CollectionUtils.isEmpty(projects)) continue;
				for (CompanyProject project : projects) {
					Integer projectid = project.getProjectid();
					boolean exists = partnerBrokerageMapper.checkPartnerBrokerageExists(projectid, partnerid);
					log.info("项目id = {} , name = {}, 是否已经分佣: {}", projectid, project.getProjectname(), exists);
					if (!exists) {
						log.info("不存在, 需要补录分佣");
						PartnerBrokerage partnerBrokerage = new PartnerBrokerage().setBrokerageno(RandomUtil.createRandomNo("PB", ""))
								.setProjectid(projectid)
								.setProjectType(1)
								.setCompid(compid)
								.setUserid(project.getUserid())
								.setPartnerid(partnerid)
								.setPartnerType(partnerCompany.getType())
								.setProjectno("P" + StringUtil.toFixedLengthNum(projectid, 9))
								.setSettleType(partnerCompany.getSettleType())
								.setRatio(partnerCompany.getRatio());
						partnerBrokerage.insert();
						log.info("佣金记录插入成功");

						if (project.getState() == CompanyProjectState.COMPLETED) {
							log.info("任务已经支付完成,计算佣金");
							//创客服务费是1%的，不记基本服务费的佣金
							Integer partnerType = partnerBrokerage.getPartnerType();
							if ((project.getProjectBaseServiceRate() == null || project.getProjectBaseServiceRate() <= 0.01d) &&
									partnerType == PartnerBrokerageType.BASIC) {
								//如果佣金表中有存在记录，则删除
								new PartnerBrokerage().delete(Condition.create()
										.eq("projectid", project.getProjectid())
										.eq("partnerid", partnerBrokerage.getPartnerid())
										.eq("partner_type", PartnerBrokerageType.BASIC));
								continue;
							}
							TradeRecord tradeRecord = new TradeRecord().selectOne(Condition.create()
																						   .eq("userid", project.getUserid())
																						   .eq("projectid", projectid)
																						   .last(" limit 1")
																						   .orderBy("tradeid", false));
							BigDecimal dealamount = project.getProjectdealamount();
							BigDecimal brokerage = dealamount.multiply(BigDecimal.valueOf(partnerBrokerage.getRatio()));
							partnerBrokerage.setBrokerage(brokerage)
									.setProjectdealamount(dealamount)
									.setProjectservicecharge(project.getProjectservicecharge())
									.setProjecttaxfee(project.getProjecttaxfee())
									.setTradeid(tradeRecord == null ? 0 : tradeRecord.getTradeid())
									.setTradeno(tradeRecord == null ? "" : tradeRecord.getTradeno())
									.setState(PartnerBrokerageState.SETTLED);
							partnerBrokerage.updateById();
							log.info("佣金金额更新成功,金额为:{}", brokerage);
						}

					}
				}

			} catch (Exception e) {
				log.error("id = {}, 报错", id, e);
			}
		}

		return SmartResult.success();
	}

	public SmartResult updateRealNameByCrowd(BaseSimpleFormBean<UpdateRealNameByCrowdFormBean> formBean) {
		UpdateRealNameByCrowdFormBean bean = formBean.getReqdata();
		//获取合伙人实名信息
		PartnerAccount partnerAccount = new PartnerAccount().selectOne(Condition.create().eq("partnerid", bean.getPartnerid()));
		if (null == partnerAccount) {
			return smartResult(StatusMsg.StatusMsg_501);
		}
		//修改
		partnerAccount.setWhetherCrowdPartner(bean.getWhetherCrowdPartner())
				.setCrowdBasicsRate(bean.getCrowdBasicsRate())
				.setCrowdCostState(bean.getCrowdCostState())
				.setCrowdCostPrimaryRate(bean.getCrowdCostPrimaryRate())
				.setCrowdCostSecondaryRate(bean.getCrowdCostSecondaryRate())
				.setCrowdCostSecondaryAmount(bean.getCrowdCostSecondaryAmount());
		if (!partnerAccount.updateById()) {
			return smartResult(StatusMsg.StatusMsg_199);
		}
		return smartResult();
	}

	public SmartResult fixBrokerageRemitState() {

		log.info("-----开始修复佣金提现未修改佣金状态的数据-----");
		List<PartnerWithdraw> list = new PartnerWithdraw().selectList(
				Condition.create().eq("state", 3).ge("finishtime", DateUtil.parseDate("2020-09-09", DateUtil.FORMAT_STYLE_2)));
		list.forEach(pw -> {
			Integer wdid = pw.getWdid();
			List<PartnerBrokerage> blist = new PartnerBrokerage().selectList(
					Condition.create().eq("wdid", wdid).ne("state", PartnerBrokerageState.WITHDRAWED));
			log.info("提现记录id={},共有{}条未修改状态的佣金记录", wdid, blist.size());
			if (!CollectionUtils.isEmpty(blist)) {
				blist.forEach(b -> {
					log.info("佣金记录id={},佣金={},修改前状态={}", b.getBrokerageid(), b.getBrokerage(), b.getState());
					b.setState(PartnerBrokerageState.WITHDRAWED).updateById();
				});
			}
		});
		log.info("-----结束修复佣金提现未修改佣金状态的数据-----");
		return SmartResult.success();
	}

	public void exportPartnerStudioWithdraws(HttpServletResponse response, String name, int state, Date from, Date to) {
		List<PartnerStudioWithdrawDto> list = partnerStudioWithdrawMapper.list(name, state, from, to);

		List<PartnerStudioRemitProjectExportDto> exportList = list.stream()
				// 将数据按 partnerid+brokerageType分组，即每个合伙人的 佣金与智众包佣金分成2组。
				.collect(Collectors.groupingBy(wd -> String.valueOf(wd.getPartnerid()) + wd.getBrokerageType())).values().stream()
				// 将每组的佣金列表合并成导出报表中的一行，即PartnerStudioRemitProjectExportDto对象
				.flatMap(wdList -> {

					List<PartnerStudioRemitProjectExportDto> expList = wdList.stream().map(wd -> {
						Integer userid = wd.getUserid();
						StudioDetailDto maker = makerStudioMapper.getStudioDetail(userid);
						double makerBaseServiceRate = coreProjectService.getMakerBaseServiceRate(maker, 0, 0, false, wd.getAmount(),
								CalcAmountType.PROCESSING);
						double makerBaseTaxRate = coreProjectService.getMakerBaseTaxRate(maker, 0, 0, false, wd.getAmount(),
								CalcAmountType.PROCESSING);

						// 转成导出对象
						return PartnerStudioRemitProjectExportDto.of(wd, maker, makerBaseServiceRate + makerBaseTaxRate);
					}).collect(Collectors.toList());

					// 计算合计总值
					BigDecimal sum = expList.stream()
							.map(PartnerStudioRemitProjectExportDto::getProjectAmount)
							.reduce(BigDecimal::add)
							.orElse(BigDecimal.ZERO);

					if (sum.doubleValue() <= 50000) {
						// 如果没有超过5万单笔项目金额，就可以合并成一笔项目
						PartnerStudioRemitProjectExportDto exportDto = expList.stream()
								.reduce(PartnerStudioRemitProjectExportDto::add)
								.get();
						expList.clear();
						expList.add(exportDto);
					}
					return expList.stream();

				}).collect(Collectors.toList());

		// 添加序号
		for (int i = 0; i < exportList.size(); i++) {
			exportList.get(i).setRow(i + 1);
		}

		String fileName = "合伙人工作室模式提现模板";
		// 填充普通变量
		Map<String, Object> map = new HashMap<>();
		// map.put("compname", "公司名称，九歌？");
		EasyExcelUtil.downloadComplex(response, docConfig.getZddPartnerStudioRemitProjectTemplatePath(), fileName, exportList, map);
	}

	public SmartResult vaccineStatus(BaseSimpleFormBean<VaccineStatusFormBean> formBean) {
		VaccineStatusFormBean reqdata = formBean.getReqdata();
		String partnerids = reqdata.getPartnerids();
		int state = reqdata.getState();
		partnerAccountMapper.vaccineStatus(partnerids, state);
		return SmartResult.success();
	}

	/**
	 * 合伙人提现申请佣金销帐
	 * @param formBean
	 * @return
	 */
	@Transactional
	public SmartResult partnerBrokerageWriteOff(BaseSimpleFormBean<PartnerWriteOffFormBean> formBean) {
		PartnerWriteOffFormBean reqdata = formBean.getReqdata();
		Integer withdrawId = reqdata.getWithdrawId();
		PartnerStudioWithdraw withdraw = new PartnerStudioWithdraw().selectById(withdrawId);
		Asserts.notNull(withdraw, StatusMsg.StatusMsg_102);
		if (withdraw.getState() == PartnerStudioWithdrawState.COMPLETED) {
			return SmartResult.fail(StatusMsg.StatusMsg_652);
		}
		//合伙人申请提现状态已完成，对应的佣金明细状态改成已提现
		withdraw.setState(PartnerStudioWithdrawState.COMPLETED)
				.setRemark(reqdata.getRemark())
				.setUpdatetime(new Date())
				.updateById();

		List<PartnerBrokerage> list = partnerBrokerageMapper.getBrokerageListByWdid(withdrawId);
		for (PartnerBrokerage pb : list) {
			pb.setState(PartnerBrokerageState.WITHDRAWED)
			  .setAdminid(formBean.getUserid())//记录当前操作人
			  .setVoucherPath(reqdata.getVoucherPath())
			  .updateById();
		}
		return SmartResult.success();
	}
}
